from dash import Input, Output, State, callback_context, no_update, ALL,html
from models import db, RepairRecord
from datetime import datetime
import dash
import base64
import os,time
from modules.generatelogs.generatelogs import write_repair_log
from flask import session


# 引入Modal组件
# from modules.repair.modals import  register_modal_callbacks
# register_modal_callbacks(dash_app)

def register_repair_respond_callbacks(dash_app):
    # 打开维修响应模态窗口并带出信息
    @dash_app.callback(
        Output("repair-respond-modal", "is_open"),
        Output("repair-respond-info", "children"),
        Output("repair-respond-person", "value"),
        Output("repair-respond-company", "value"),
        Output("repair-respond-expected-date", "date"),
        Output("repair-respond-remarks", "value"),
        Output("repair-respond-alert", "is_open"),
        Output("repair-respond-alert", "children"),
        Input("repair-respond-button", "n_clicks"),  # 只监听右下角按钮
        State("repair-records-table", "data"),
        State("repair-details-record-id-store", "data"),  # 需要知道当前选中的记录id
        prevent_initial_call=True
    )
    def open_repair_respond_modal(n_clicks, table_data, record_id):
        if not n_clicks or not record_id:
            return dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, False, ""
        # 查找该条记录
        record = next((r for r in table_data if r["id"] == record_id), None)
        if not record:
            return dash.no_update, "未找到维修记录", "", "", None, "", True, "未找到维修记录"
        from models import Product  # 确保导入 Product
        ctx = callback_context
        if not ctx.triggered:
            raise dash.exceptions.PreventUpdate
        # 找到被点击的按钮index
        btn_id = ctx.triggered[0]["prop_id"].split(".")[0]
        try:
            record_id = int(eval(btn_id)["index"])
        except Exception:
            return no_update, no_update, no_update, no_update, no_update, no_update, True, "无法识别维修记录ID"
        # 查找该条记录
        record = next((r for r in table_data if r["id"] == record_id), None)
        # print(f'callbacks2 P32 record:{record}')
        if not record:
            return no_update, no_update, no_update, no_update, no_update, no_update, True, "未找到维修记录"
        # 用 product_id 查 Product 表
        product_id = record.get("product_id")
        # print(f'callbacks2 P37 product_id:{product_id},record:{record}')
        product_info = None
        if product_id:
            product = db.session.query(Product).filter_by(id=product_id).first()
            if product:
                product_info = [
                    html.Div(f"设备详细信息："),
                    html.Div(f"设备ID: {product.id}"),
                    html.Div(f"设备名称: {product.product_name}"),
                    html.Div(f"设备编号: {product.product_code}"),
                    html.Div(f"品牌: {getattr(product, 'manufacturer', '')}"),
                    html.Div(f"型号: {getattr(product, 'model', '')}"),
                    html.Div(f"机构: {getattr(product, 'org_short_name_c', '')}"),
                    html.Div(f"科室: {getattr(product, 'department_name', '')}"),
                    html.Div(f"采购日期: {product.purchase_date.strftime('%Y-%m-%d') if product.purchase_date else ''}"),
                    # html.Div(f"价格: {product.price}"),
                    html.Div(f"运行状态: {getattr(product, 'running_status', '')}"),
                ]
            else:
                product_info = [html.Div("未找到设备详细信息")]
        else:
            product_info = [html.Div("无设备ID，无法查询设备信息")]

        # 展示信息（维修单信息 + 设备详细信息）
        info = html.Div([
            html.Div(f"维修单号: {record['id']}"),
            html.Div(f"设备ID: {record.get('product_id', '')}"),
            html.Div(f"设备名称: {record.get('product_name', '')}"),
            html.Div(f"设备编号: {record.get('product_code', '')}"),
            # html.Div(f"品牌: {record.get('product_brand', '')}"),
            # html.Div(f"型号: {record.get('product_model', '')}"),
            html.Div(f"机构: {record.get('org_name', '')}"),
            html.Div(f"科室: {record.get('department_name', '')}"),
            html.Div(f"故障描述: {record.get('fault_description', '')}"),
            html.Div(f"报修时间: {record.get('report_date', '')}"),
            html.Div(f"报修人: {record.get('repair_caller', '')}"),
            html.Hr(),
            *product_info
        ],style={"marginTop": "80px"})
        return True, info, "", "", None, "", False, ""

    # 关闭模态窗口
    @dash_app.callback(
        Output("repair-respond-modal", "is_open", allow_duplicate=True),
        Input("repair-respond-cancel", "n_clicks"),
        prevent_initial_call=True
    )
    def close_repair_respond_modal(n_cancel):
        if n_cancel:
            return False
        return no_update

    # 提交维修响应
    @dash_app.callback(
        Output('repair-refresh-flag-answer', 'data'),
        Output("repair-respond-modal", "is_open", allow_duplicate=True),
        Output("repair-respond-alert", "is_open", allow_duplicate=True),
        Output("repair-respond-alert", "children", allow_duplicate=True),
        Input("repair-respond-confirm", "n_clicks"),
        State("repair-respond-person", "value"),
        State("repair-respond-company", "value"),
        State("repair-respond-expected-date", "date"),
        State("repair-respond-remarks", "value"),
        State("repair-respond-info", "children"),
        State("repair-details-record-id-store", "data"), # 获取当前记录ID
        State("repair-respond-repairtype", "value"), # 新增：获取维修类型的值
        prevent_initial_call=True
    )
    def submit_repair_respond(n_submit, person, company, expected_date, remarks, info_children, record_id, repair_type_value):
        if not n_submit:
            raise dash.exceptions.PreventUpdate
        try:
            record_id = None
            children = info_children.get("props", {}).get("children", []) if isinstance(info_children, dict) else info_children
            for child in children:
                text = ""
                if isinstance(child, dict):
                    text = child.get("props", {}).get("children", "")
                elif isinstance(child, str):
                    text = child
                if "维修单号" in text:
                    record_id = int(text.split(":")[1].strip())
                    break
            if not record_id:
                return dash.no_update, True, "无法获取维修单号"
        except Exception as e:
            return dash.no_update, True, "无法解析维修单号"
        if not person or not company or not expected_date:
            return dash.no_update, True, "请填写所有必填项"
        record = db.session.query(RepairRecord).filter_by(id=record_id).first()
        if not record:
            return dash.no_update, True, "未找到维修记录"
        record.repair_person = person
        record.repair_company = company
        record.expected_completion_date = datetime.strptime(expected_date, "%Y-%m-%d").date()
        record.remarks = remarks
        record.repair_status = "维修中"
        record.repair_answer_date = datetime.now() # 新增：记录响应时间
        record.repair_type = repair_type_value # 新增：记录维修类型
        db.session.commit()
        from flask import session
        from models import User
        user_id = session.get("user_id")
        if user_id:
            user = User.query.get(user_id)
            username = user.username if user else "匿名用户"
        else:
            username = "匿名用户"
        write_repair_log(
            action="维修响应",
            username=username,
            device_id=record.product_id,
            record_id=record.id,
            message=f"维修人员：{person},维修公司: {company}, 预计完成: {expected_date}, 备注: {remarks}, 维修类型: {repair_type_value}"
        )
        # 关键：返回一个带时间戳的字典，确保每次都不同，触发表格刷新
        return {"refresh": True, "ts": time.time()}, False, False, ""

    @dash_app.callback(
        Output("upload-proof-modal", "is_open"),
        Output("upload-proof-alert", "is_open"),
        Output("upload-proof-alert", "children"),
        Output("proof-preview-refresh", "data"),  # 新增
        Input("upload-proof-btn", "n_clicks"),
        Input("upload-proof-cancel", "n_clicks"),
        Input("upload-proof", "contents"),
        State("repair-details-record-id-store", "data"),
        State("upload-proof", "filename"),
        prevent_initial_call=True
    )
    def handle_upload_proof(open_click, cancel_click, upload_contents, record_id, upload_filename):
        import time
        ctx = dash.callback_context
        if not ctx.triggered:
            raise dash.exceptions.PreventUpdate
        trigger = ctx.triggered[0]["prop_id"].split(".")[0]
        if trigger == "upload-proof-btn":
            if not open_click or open_click == 0:
                return dash.no_update, dash.no_update, dash.no_update, dash.no_update
            return True, False, "", dash.no_update
        if trigger == "upload-proof-cancel":
            return False, False, "", dash.no_update
        if trigger == "upload-proof" and upload_contents and record_id:
            # 解析图片内容
            content_type, content_string = upload_contents.split(',')
            img_data = base64.b64decode(content_string)
            # 构造保存路径
            save_dir = "static/proofs"
            os.makedirs(save_dir, exist_ok=True)
            save_path = os.path.join("static","proofs", f"工单{record_id}.jpg")
            with open(save_path, "wb") as f:
                f.write(img_data)
            # 更新数据库
            record = db.session.query(RepairRecord).filter_by(id=record_id).first()
            if record:
                record.proof = save_path
                db.session.commit()
                # 新增：写入日志
                from flask import session
                from models import User
                user_id = session.get("user_id")
                if user_id:
                    user = User.query.get(user_id)
                    username = user.username if user else "匿名用户"
                else:
                    username = "匿名用户"
                write_repair_log(
                    action="上传工单",
                    username=username,
                    device_id=record.product_id,
                    record_id=record_id,
                    message=f"工单上传人：{username}，上传成功"
                )
                return True, True, "上传成功！", str(time.time())  # 用时间戳强制刷新
            else:
                # 新增：写入日志
                from flask import session
                from models import User
                user_id = session.get("user_id")
                if user_id:
                    user = User.query.get(user_id)
                    username = user.username if user else "匿名用户"
                else:
                    username = "匿名用户"
                write_repair_log(
                    action="上传工单",
                    username=username,
                    device_id=record.product_id,
                    record_id=record_id,
                    message=f"工单上传人：{username}，上传失败"
                )
                return True, True, "未找到维修记录", dash.no_update
        return dash.no_update, dash.no_update, dash.no_update, dash.no_update

    
    @dash_app.callback(
        Output("proof-preview-area", "children"),
        Input("repair-details-record-id-store", "data"),
        Input("proof-preview-refresh", "data"),
    )
    def update_proof_preview(record_id, refresh_flag):
        if not record_id:
            return ""
        record = db.session.query(RepairRecord).filter_by(id=record_id).first()
        if not record or not record.proof:
            return ""
        ts = refresh_flag or ""
        file_url = "/" + record.proof.replace("\\", "/")
        if ts:
            file_url_with_ts = f"{file_url}?v={ts}"
        else:
            file_url_with_ts = file_url
        # 用 splitext 判断类型，忽略参数
        ext = os.path.splitext(file_url)[-1].lower()
        if ext in [".jpg", ".jpeg", ".png", ".gif"]:
            preview = html.Img(src=file_url_with_ts, style={"maxWidth": "100%", "margin": "10px 0"})
        elif ext == ".pdf":
            preview = html.Iframe(src=file_url_with_ts, style={"width": "100%", "height": "400px", "margin": "10px 0"})
        else:
            preview = html.Div("暂不支持预览该文件类型")
        download_btn = html.A("下载工单", href=file_url_with_ts, download=True, target="_blank", className="btn btn-primary mt-2")
        return html.Div([preview, download_btn])

        # 重置按钮
    @dash_app.callback(
        Output('repair-org-filter', 'value', allow_duplicate=True),
        Output('repair-dept-filter', 'value', allow_duplicate=True),
        Output('repair-id-filter', 'value', allow_duplicate=True),
        Output('repair-status-filter', 'value', allow_duplicate=True),
        Output('repair-date-filter', 'start_date', allow_duplicate=True),
        Output('repair-date-filter', 'end_date', allow_duplicate=True),
        Output('repair-keyword-filter', 'value', allow_duplicate=True),
        Output('repair-person-filter', 'value', allow_duplicate=True),
        Output('repair-caller-filter', 'value', allow_duplicate=True),
        Input('repair-reset-button', 'n_clicks'),
        prevent_initial_call=True
    )
    def reset_filters(n_clicks):
        if n_clicks:
            return None, None, None, None, None, None, "", [], []
        return dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update
     